<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>share desktop both</title>
</head>
<body>
<div>
    <video id="localVideo" width="480px" height="320px" autoplay controls></video>
    <video id="remoteVideo" width="480px" height="320px" autoplay controls></video>
    <fieldset>
        <legend>服务器</legend>
        <button id="start" onclick="startPeer()">Start</button>
        <button onclick="shareDesktop()">切换桌面演示</button>
        <button onclick="closeDesktop()">关闭桌面演示</button>
    </fieldset>
    <br>
    <fieldset>
        <legend>观看方</legend>
        <button id="watch" onclick="startWatch()">Watch</button>
        <button onclick="shareDesktop()">切换桌面演示</button>
        <button onclick="closeDesktop()">关闭桌面演示</button>
    </fieldset>
</div>
<script>
    let pc1, pc2, ws, localStream, flag, sender

    function startPeer() {
        document.querySelector('#start').disabled = true
        ws = new WebSocket('ws://127.0.0.1:3001');
        ws.onopen = function () {
            ws.send(JSON.stringify({
                type: 'connect',
                from: 'pc1',
                to: null,
                data: null
            }));
        }
        ws.onmessage = function (res) {
            let temp = JSON.parse(res.data)
            if (temp.type === 'answer') {
                console.log('收到answer...')
                pc1.setRemoteDescription(temp.data).then(function () {
                    console.log('Peer Connection is success...')
                })
            } else if (temp.type === 'candidate') {
                console.log('收到candidate...')
                pc1.addIceCandidate(new RTCIceCandidate(temp.data)).then(() => {
                    console.log('candidate添加成功')
                }).catch(handleError)
            } else if (temp.type === 'watch') {
                pc1_createOffer()
            }
        }
        navigator.mediaDevices.getUserMedia({
            audio: false,
            video: true
        }).then(handleSuccess).catch(handleError)

        function handleSuccess(stream) {
            document.getElementById("localVideo").srcObject = stream
            localStream = stream
            pc1 = new RTCPeerConnection()
            let track = stream.getTracks()[0]
            sender = pc1.addTrack(track, stream)
            pc1.onicecandidate = function (event) {
                console.log('发送candidate...')
                if (event.candidate) {
                    sendInfo({
                        type: 'candidate',
                        from: 'pc1',
                        to: 'pc2',
                        data: event.candidate
                    })
                }
            }
            pc1.onnegotiationneeded = function () {
                console.log('需要协商...')
                if(flag){
                  pc1_createOffer()
                }
            }
            pc1.ontrack = function (e) {
               console.log('获得remote的视频流...', e.streams)
               document.getElementById("remoteVideo").srcObject = e.streams[0]
            }
        }

        function handleError(err) {
            console.log(err)
        }
    }

    function startWatch() {
        document.querySelector('#watch').disabled = true
        ws = new WebSocket('ws://127.0.0.1:3001');
        ws.onopen = function () {
            ws.send(JSON.stringify({
                type: 'connect',
                from: 'pc2',
                to: null,
                data: null
            }));
            setTimeout(() => {
                ws.send(JSON.stringify({
                    type: 'watch',
                    from: 'pc2',
                    to: 'pc1',
                    data: null
                }))
            }, 500)
        }
        ws.onmessage = function (res) {
            let temp = JSON.parse(res.data)
            if (temp.type === 'offer') {
                console.log('收到offer...')
                if (pc2) {
                    pc2.setRemoteDescription(temp.data).then(function () {
                        pc2.createAnswer().then((answer) => {
                            pc2.setLocalDescription(answer).then(() => {
                                sendInfo({
                                    type: 'answer',
                                    from: 'pc2',
                                    to: 'pc1',
                                    data: answer
                                })
                            })
                        })
                    })
                    return
                }

                navigator.mediaDevices.getUserMedia({
                    audio: false,
                    video: true
                }).then(handleSuccess).catch(handleError)

                function handleSuccess(stream) {
                  document.getElementById("localVideo").srcObject = stream
                  localStream = stream
                  pc2 = new RTCPeerConnection()
                  let track = stream.getTracks()[0]
                  sender = pc2.addTrack(track, stream)
                  pc2.ontrack = function (e) {
                      console.log('获得应答方的视频流...', e.streams)
                      document.getElementById("remoteVideo").srcObject = e.streams[0]
                  }
                  pc2.onicecandidate = function (event) {
                      console.log('发送candidate...')
                      if (event.candidate) {
                          sendInfo({
                              type: 'candidate',
                              from: 'pc2',
                              to: 'pc1',
                              data: event.candidate
                          })
                      }
                  }
                  pc2.onnegotiationneeded = function () {
                      console.log('需要协商...')
                  }
                  pc2.setRemoteDescription(temp.data).then(function () {
                      pc2_createAnswer()
                  })
                }

                function handleError(err) {
                    console.log(err)
                }

            } else if (temp.type === 'candidate') {
                console.log('收到candidate...')
                pc2.addIceCandidate(new RTCIceCandidate(temp.data)).then(() => {
                    console.log('candidate添加成功')
                })
            }
        }
    }

    function pc1_createOffer() {
        pc1.createOffer().then((offer) => {
            pc1.setLocalDescription(offer).then(() => {
                console.log('发送offer...')
                sendInfo({
                    type: 'offer',
                    from: 'pc1',
                    to: 'pc2',
                    data: offer
                })
            })
        })
    }

    function pc2_createAnswer() {
        pc2.createAnswer().then((answer) => {
            pc2.setLocalDescription(answer).then(() => {
                sendInfo({
                    type: 'answer',
                    from: 'pc2',
                    to: 'pc1',
                    data: answer
                })
            })
        })
    }

    function sendInfo(info) {
        ws.send(JSON.stringify(info))
    }

    function shareDesktop() {
        flag = true
        console.log('切换桌面演示...')
        navigator.mediaDevices.getDisplayMedia({audio: false, video: true})
            .then(stream => {
                document.querySelector('#localVideo').srcObject = stream
                let track = stream.getTracks()[0]
                sender.replaceTrack(track).then(() => {
                    console.log('replace track success...')
                })
            })
            .catch(err => {
                console.log(err)
            })
    }

    function closeDesktop() {
       console.log('关闭桌面演示...')
       let pc = pc1 ? pc1 : pc2
       pc.getSenders()[0].replaceTrack(localStream.getTracks()[0]).then(() => {
           document.querySelector('#localVideo').srcObject = localStream
           console.log('replace track success...')
       }).catch(err => {
           console.log(err.toString())
       })
    }
</script>
</body>
</html>
